import fs from 'fs';
import path from 'path';
import sharp from 'sharp';
import multer from 'multer';
import { md5 } from '~/server/utils/util.crypto';
import { FileModel } from '~/server/models/file.model';

// 配置 multer，上传到 server/upload 目录
const uploadDir = path.resolve(process.cwd(), 'public/resource');
console.log('uploadDir: ', uploadDir);

if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true });

const storage = multer.memoryStorage();

const upload = multer({
	storage,
	limits: {
		// 文件上传大小限制为 1G
		fileSize: 1024 * 1024 * 1024,
	},
});

export default defineEventHandler(async (event): Promise<any> => {
	try {
		// 处理 multipart/form-data
		await new Promise((resolve, reject) => {
			upload.array('files')(event.node.req as any, event.node.res as any, (err) => {
				if (err) reject(err);
				else resolve(null);
			});
		});

		// @ts-ignore
		const files = event.node.req.files as Express.Multer.File[];
		if (!files || files.length === 0) {
			return { code: 0, message: '未检测到上传文件' };
		}

		const results = [];
		for (const file of files) {
			try {
				const fileMd5 = md5(file.buffer);

				// 查找数据库是否已存在
				const exist = await FileModel.findOne({ md5: fileMd5 });
				if (exist) {
					results.push(exist);
					continue;
				}

				// 生成文件名
				const ext = path.extname(file.originalname).toLowerCase();

				// 修复中文文件名乱码
				const safeOriginalName = Buffer.from(file.originalname, 'latin1').toString('utf8');

				const isImage = ['.jpg', '.jpeg', '.png', '.webp', '.gif', '.bmp'].includes(ext);

				let saveName = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;

				let savePath = '';

				let mimeType = file.mimetype;

				if (isImage) {
					// 转 webp
					saveName += '.webp';

					savePath = path.join(uploadDir, saveName);

					await sharp(file.buffer).webp().toFile(savePath);

					mimeType = 'image/webp';
				} else {
					// 其他文件原格式保存
					saveName += ext;

					savePath = path.join(uploadDir, saveName);

					fs.writeFileSync(savePath, file.buffer);
				}

				// 生成 url 路径（假设静态资源映射 /upload）
				const url = `/resource/${saveName}`;

				// 写入数据库
				const doc = await FileModel.create({
					name: saveName,
					originalName: safeOriginalName,
					mimeType,
					md5: fileMd5,
					path: savePath,
					url,
					size: file.size,
				});

				results.push(doc);
			} catch (fileErr: any) {
				results.push({
					error: true,
					originalName: file.originalname,
					message: fileErr?.message || '单文件处理失败',
				});
			}
		}

		return { code: 1, message: '上传处理完成', data: results };
	} catch (err: any) {
		return { code: 0, message: err?.message || '文件上传失败' };
	}
});
